#ifndef DW_GRAPHICS_OCTREE_H
# define DW_GRAPHICS_OCTREE_H

#	include "boundingvolume.h"

namespace dw
{
namespace graphics
{

using maths::Point3f;

class Node;
class Frustum;

class Octree
{
// Constructors
public:

	/// Default constructor
																	Octree(const unsigned depth = 0);
	/// Create an octree node with the given extents
																	Octree(const Point3f& min, const Point3f& max, const unsigned depth = 0);

																	~Octree();

// Methods
public:

	/// Returns the bounding box of this octree node
	const AABBox& getBoundingBox() const { return _boundingBox; }			

	/// Add an element to this octree node
	void insertElement(Node* element);
	/// Remove an element from this octree node
	void removeElement(Node* element);
	/// Subdivide this octree node
	void subdivide();
	/// Collapse this octree node
	void collapse();
	/// Balance this octree node by distributing the elements upon the children
	void balance();
	/// Returns if this octree node intersects with the given element (-Scene- Node)
	bool intersects(Node* element);
	/// Returns if this octree node has children
	bool hasChildren() const { return _children[0] ? true : false; }
	/// Returns if this octree node is empty (no element)
	bool isEmpty() const { return _elements.empty(); }



	/// Render the bounding box of this octree node and its children recursively
	void render(Frustum* frustum);

// Fields
private:

	/// Children of this octree node (octants)
	Octree* _children[8];
	/// Elements contained in this octree node
	std::set< Node* >									_elements;
	/// Axis aligned bounding box of this octree node
	AABBox _boundingBox;

	unsigned _depth;

};

} // namespace graphics
} // namespace dw

#	endif // DW_GRAPHICS_OCTREE_H
